package com.example.analysis.service.impl;

import com.example.analysis.domain.ScoreInfo;
import com.example.analysis.dto.CourseStatsDTO;
import com.example.analysis.mapper.ScoreMapper;
import com.example.analysis.service.CourseStatsService;
import com.example.analysis.utils.Response1;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CourseStatsServiceImpl implements CourseStatsService {
    @Resource
    private ScoreMapper scoreMapper;


    //学生平时成绩波动性
    @Override
    public Response1<List<CourseStatsDTO>> getCourseStats(String semester) {
        List<ScoreInfo> rawData = scoreMapper.findAllDailyScores(semester);
        Map<String, List<Double>> courseScores = new HashMap<>();
        // 数据分组处理
        for (ScoreInfo row : rawData) {
            String courseId =  row.getSubId();
            Double score = row.getDayScore();
            courseScores.computeIfAbsent(courseId, k -> new ArrayList<>()).add(score);
        }
        // 计算统计指标
        List<CourseStatsDTO> stats = courseScores.entrySet().stream()
                .map(entry -> calculateStats(entry.getKey(), entry.getValue()))
                .collect(Collectors.toList());

        return new Response1<>(20000, "Success", stats);
    }


    private CourseStatsDTO calculateStats(String courseId, List<Double> scores) {
        System.out.println("courseID"+courseId);
        System.out.println("scres"+scores);
        // 防御空列表和null列表
        if (scores == null || scores.isEmpty()) {
            return new CourseStatsDTO(courseId, 0.0, 0.0, 0.0, 0.0, 0);
        }

        // 过滤null值并转换为原始类型
        double[] validScores = scores.stream()
                .filter(score -> score != null && score > 0) // 过滤null元素
                .mapToDouble(Double::doubleValue)
                .toArray();

        // 处理全空数据的情况
        if (validScores.length == 0) {
            return new CourseStatsDTO(courseId, 0.0, 0.0, 0.0, 0.0, 0);
        }

        // 计算统计指标
        DoubleSummaryStatistics stats = Arrays.stream(validScores).summaryStatistics();
        int count = (int) stats.getCount();


        // 仅当有效数据超过10条时返回统计结果
        if (count <= 10) {
            return new CourseStatsDTO(courseId, 0.0, 0.0, 0.0, 0.0, 0);
        }


        // 计算标准差
        double avg = stats.getAverage();
        double variance = scores.stream()
                .mapToDouble(score -> Math.pow(score - avg, 2))
                .average()
                .orElse(0.0);
        double stdDev = Math.sqrt(variance);

        return new CourseStatsDTO(
                courseId,
                stats.getMin(),
                stats.getMax(),
                avg,
                stdDev,
                count
        );
    }
}
